<template>
    <div class="el-transfer">
        <transfer-panel
                v-bind="$props"
                ref="leftPanel"
                :data="sourceData"
                :title="titles[0] || t('el.transfer.titles.0')"
                :default-checked="leftDefaultChecked"
                :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
                @checked-change="onSourceCheckedChange">
            <slot name="left-footer"></slot>
        </transfer-panel>
        <div class="el-transfer__buttons">
            <el-button
                    type="primary"
                    :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
                    @click.native="addToLeft"
                    :disabled="rightChecked.length === 0">
                <i class="el-icon-arrow-left"></i>
                <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
            </el-button>
            <el-button
                    type="primary"
                    :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
                    @click.native="addToRight"
                    :disabled="leftChecked.length === 0">
                <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
                <i class="el-icon-arrow-right"></i>
            </el-button>
        </div>
        <transfer-panel
                v-bind="$props"
                ref="rightPanel"
                :data="targetData"
                :title="titles[1] || t('el.transfer.titles.1')"
                :default-checked="rightDefaultChecked"
                :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
                @checked-change="onTargetCheckedChange">
            <slot name="right-footer"></slot>
        </transfer-panel>
    </div>
</template>

<script>
    import ElButton from 'element-ui/packages/button';
    import Emitter from 'element-ui/src/mixins/emitter';
    import Locale from 'element-ui/src/mixins/locale';
    import TransferPanel from './transfer-panel.vue';
    import Migrating from 'element-ui/src/mixins/migrating';

    export default {
        name: 'ElTransfer',

        mixins: [Emitter, Locale, Migrating],

        components: {
            TransferPanel,
            ElButton
        },

        props: {
            data: {
                type: Array,
                default() {
                    return [];
                }
            },
            titles: {
                type: Array,
                default() {
                    return [];
                }
            },
            buttonTexts: {
                type: Array,
                default() {
                    return [];
                }
            },
            filterPlaceholder: {
                type: String,
                default: ''
            },
            filterMethod: Function,
            leftDefaultChecked: {
                type: Array,
                default() {
                    return [];
                }
            },
            rightDefaultChecked: {
                type: Array,
                default() {
                    return [];
                }
            },
            renderContent: Function,
            value: {
                type: Array,
                default() {
                    return [];
                }
            },
            format: {
                type: Object,
                default() {
                    return {};
                }
            },
            filterable: Boolean,
            props: {
                type: Object,
                default() {
                    return {
                        label: 'label',
                        key: 'key',
                        disabled: 'disabled'
                    };
                }
            },
            targetOrder: {
                type: String,
                default: 'original'
            }
        },

        data() {
            return {
                leftChecked: [],
                rightChecked: []
            };
        },

        computed: {
            dataObj() {
                const key = this.props.key;
                return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {});
            },

            sourceData() {
                return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1);
            },

            targetData() {
                if (this.targetOrder === 'original') {
                    return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1);
                } else {
                    return this.value.reduce((arr, cur) => {
                        const val = this.dataObj[cur];
                        if (val) {
                            arr.push(val);
                        }
                        return arr;
                    }, []);
                }
            },

            hasButtonTexts() {
                return this.buttonTexts.length === 2;
            }
        },

        watch: {
            value(val) {
                this.dispatch('ElFormItem', 'el.form.change', val);
            }
        },

        methods: {
            getMigratingConfig() {
                return {
                    props: {
                        'footer-format': 'footer-format is renamed to format.'
                    }
                };
            },

            onSourceCheckedChange(val, movedKeys) {
                this.leftChecked = val;
                if (movedKeys === undefined) return;
                this.$emit('left-check-change', val, movedKeys);
            },

            onTargetCheckedChange(val, movedKeys) {
                this.rightChecked = val;
                if (movedKeys === undefined) return;
                this.$emit('right-check-change', val, movedKeys);
            },

            addToLeft() {
                let currentValue = this.value.slice();
                this.rightChecked.forEach(item => {
                    const index = currentValue.indexOf(item);
                    if (index > -1) {
                        currentValue.splice(index, 1);
                    }
                });
                this.$emit('input', currentValue);
                this.$emit('change', currentValue, 'left', this.rightChecked);
            },

            addToRight() {
                let currentValue = this.value.slice();
                const itemsToBeMoved = [];
                const key = this.props.key;
                this.data.forEach(item => {
                    const itemKey = item[key];
                    if (
                        this.leftChecked.indexOf(itemKey) > -1 &&
                        this.value.indexOf(itemKey) === -1
                    ) {
                        itemsToBeMoved.push(itemKey);
                    }
                });
                currentValue = this.targetOrder === 'unshift'
                    ? itemsToBeMoved.concat(currentValue)
                    : currentValue.concat(itemsToBeMoved);
                this.$emit('input', currentValue);
                this.$emit('change', currentValue, 'right', this.leftChecked);
            },

            clearQuery(which) {
                if (which === 'left') {
                    this.$refs.leftPanel.query = '';
                } else if (which === 'right') {
                    this.$refs.rightPanel.query = '';
                }
            }
        }
    };
</script>
